package com.tianji.service.impl;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.RandomUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.config.SessionProperties;
import com.tianji.entity.pojo.ChatSession;
import com.tianji.entity.vo.ChatHistoryVO;
import com.tianji.entity.vo.MessageVO;
import com.tianji.entity.vo.SessionVO;
import com.tianji.enums.MessageTypeEnum;
import com.tianji.mapper.ChatSessionMapper;
import com.tianji.memory.MessageUtil;
import com.tianji.service.ChatSessionService;
import com.tianji.util.RedisKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.messages.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.Thread.sleep;

@Slf4j
@Service
public class ChatSessionServiceImpl extends ServiceImpl<ChatSessionMapper, ChatSession> implements ChatSessionService {

    @Autowired
    private SessionProperties sessionProperties;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Override
    public SessionVO getSession(Integer num) {
        //获取当前登录用户信息
        Long userId = UserContext.getUser();
        String sessionId = IdUtil.fastSimpleUUID();
        //1. 将新增的Session会话对象保存到数据库
        ChatSession build = ChatSession.builder()
                .userId(userId)
                .sessionId(sessionId)
                .build();
        save( build);
        //2. 构建一个SessionVO对象返回给前端
        SessionVO sessionVO = BeanUtils.toBean(sessionProperties, SessionVO.class);
        sessionVO.setSessionId(sessionId);
        sessionVO.setExamples(RandomUtils.randomEleList(sessionProperties.getExamples(), num));
        return sessionVO;
    }

    @Override
    public List<SessionVO.Example> getHot(Integer num) {
        //随机数，换一批问题
        //获取当前请求的id
        List<SessionVO.Example> examples = RandomUtils.randomEleList(sessionProperties.getExamples(), num);
        return examples;
    }

    /**
     * 查询会话详情
     * @param sessionId
     * @return
     */
    @Override
    public List<MessageVO> getChatMessage(String sessionId) {
        //根据sessionId 和 userID 构建Key，去查Redis中的会话历史
        String userId = UserContext.getUser()+"";
        String key = RedisKeyUtil.getKey(sessionId, userId);
        List<String> range = redisTemplate.opsForList().range(key, 0, -1);
        if (CollUtils.isEmpty(range)){
            return null;
        }
        List<Message> collect = range.stream().map(jsonStr -> MessageUtil.toMessage(jsonStr)).collect(Collectors.toList());
        //将message转化为MessageVO
        List<MessageVO> list = collect.stream().map(message -> MessageVO.builder()
                .content(message.getText())
                .type(MessageTypeEnum.valueOf(message.getMessageType().name()))
                .build()).toList();
        return list;
    }

    @Override
    @Async("myPool")
    public void updateTitle(String sessionId, String title, Long userId) {
        try {
            sleep(20000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //1. 根据sessionId 和用户Id查询出对应的会话
        LambdaQueryWrapper<ChatSession> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ChatSession::getUserId, userId)
                .eq(ChatSession::getSessionId, sessionId)
                .isNull(ChatSession::getTitle);
        ChatSession one = getOne(lqw);
        if (BeanUtils.isEmpty(one)) { // 此时不是第一次，不用管
            return;
        }
        //是第一次，需要设置标题
        one.setTitle(title);
        updateById(one);

    }

/*    @Override
    public Map<String, List<ChatHistoryVO>> queryHistorySession() {
        //思路整理：根据userId，去数据库中查出属于这个用户的会话内容
        //表中的内容足以满足前端的需要，核心是将内容封装成前端需要的格式
        Long userId = UserContext.getUser();
        //构建查询条件进行查询
        LambdaQueryWrapper<ChatSession> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ChatSession::getUserId, userId)
                .isNotNull(ChatSession::getTitle)
                .orderByDesc(ChatSession::getUpdateTime);
        List<ChatSession> list = list(lqw);
        //核心，将这个集合转换成前端需要的Map,先试传统方法
        //逐个将ChatSession转换成ChatHistoryVO
        List<ChatHistoryVO> collect = list.stream().map(chatSession -> ChatHistoryVO
                .builder()
                .sessionId(chatSession.getSessionId())
                .title(chatSession.getTitle())
                .updateTime(chatSession.getUpdateTime())
                .build())
                .collect(Collectors.toList());

        //开始准备HashMap
        //准备四个键值
        String key1 = "1年以上";
        String key2 = "最近1年";
        String key3 = "最近30天";
        String key4 = "当天";
        //遍历一下得到的集合，根据updateTime进行分类，加入不同的集合中
        Map<String, List<ChatHistoryVO>> map = new LinkedHashMap<>();
        map.put(key4,new ArrayList<>());
        map.put(key3,new ArrayList<>());
        map.put(key2,new ArrayList<>());
        map.put(key1,new ArrayList<>());

        for (ChatHistoryVO vo : collect) {
            LocalDateTime updateTime = vo.getUpdateTime();
            long between = ChronoUnit.DAYS.between(updateTime, LocalDateTime.now());

            if(between == 0){
                map.get(key4).add(vo);
            } else if (between <= 30){
                map.get(key3).add(vo);
            } else if (between <= 365){
                map.get(key2).add(vo);
            }else{
                map.get(key1).add(vo);
            }
        }
        //最后处理一下，如果键值对应ArrayList里面没有数据，就把它删掉
        map.entrySet().removeIf(entry -> CollUtils.isEmpty(entry.getValue()));
        return map;
    }*/

    //文艺青年写法


    @Override
    public Map<String, List<ChatHistoryVO>> queryHistorySession() {
        String key1 = "1年以上";
        String key2 = "最近1年";
        String key3 = "最近30天";
        String key4 = "当天";

        //构建查询条件进行查询
        LambdaQueryWrapper<ChatSession> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ChatSession::getUserId, UserContext.getUser())
                .isNotNull(ChatSession::getTitle)
                .orderByDesc(ChatSession::getUpdateTime);
        List<ChatSession> list = list(lqw);

        LinkedHashMap<String, List<ChatHistoryVO>> map = list.stream().map(chatSession -> ChatHistoryVO
                
                        .builder()
                        .sessionId(chatSession.getSessionId())
                        .title(chatSession.getTitle())
                        .updateTime(chatSession.getUpdateTime())
                        .build())
                .collect(Collectors.groupingBy(new SFunction<ChatHistoryVO, String>() {
                    @Override
                    public String apply(ChatHistoryVO vo) {
                        LocalDateTime updateTime = vo.getUpdateTime();
                        long between = ChronoUnit.DAYS.between(updateTime, LocalDateTime.now());

                        if (between == 0) {
                            return key4;
                        } else if (between <= 30) {
                            return key3;
                        } else if (between <= 365) {
                            return key2;
                        } else {
                            return key1;
                        }
                    }
                }, LinkedHashMap::new, Collectors.toList()));
        return map;
    }
}
